package evs.gateway;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import evs.location.EntityDom;

public class ExternalServiceServlet extends GatewayServlet
{
    private static final long serialVersionUID = 5074794108844396215L;

    @Override
    protected void doGet( HttpServletRequest request, HttpServletResponse response )
                    throws ServletException, IOException
    {
        String searchTerm = request.getParameter( "searchTerm" );
        
        if ( searchTerm == null || searchTerm.isEmpty() )
        {
            response.sendError( HttpServletResponse.SC_BAD_REQUEST, "No search term given!" );
            return;
        }
        
        List<String> storageUrls = _getStorageUrls();

        EntityDom results = new EntityDom();
        results.name = "results";

        for ( String storageURL : storageUrls )
        {
            EntityDom storageResults = _getResultsFromGateway( storageURL, searchTerm );
            ResultMerger.merge( storageResults, results, "Person" );
        }

        try
        {
            if ( "application/json".equals( request.getContentType() ) )
            {
                response.getWriter().write( results.toJson() );
            }
            else
            {
                response.getWriter().write( results.toXML() );
            }
        }
        catch ( IOException e )
        {
            throw new ServletException( e );
        }
    }

    @Override
    protected String _getIndexUrl() throws MalformedURLException
    {
        String nonce = Integer.toString( ( (int) ( Integer.MAX_VALUE * Math.random() ) ) );
        String encryptedNonce = _securityManager.encryptWithPrivateKey( nonce );
        
        String baseUrl = super._getIndexUrl();
        
        return baseUrl + "?nonce=" + nonce + "&encryptedNonce=" + encryptedNonce;
    }

    private EntityDom _getResultsFromGateway( String storageURL, String searchTerm ) 
        throws ServletException
    {
        try
        {
            // this is a hack!
            String serviceName = storageURL.substring( storageURL.lastIndexOf( "/" ) + 1 );
            
            String requestBody = "searchTerm=" + searchTerm;
            String encryptedRequest = _securityManager.encrypt( requestBody, serviceName );
            
            String response = _http.post( storageURL, encryptedRequest, "application/xml" );
            String decryptedResponse = _securityManager.decryptWithPrivateKey( response );

            return EntityDom.fromXML( decryptedResponse );
        }
        catch ( Exception e )
        {
            throw new ServletException( e );
        }
    }
    
    private List<String> _getStorageUrls() throws ServletException
    {
        try
        {
            String indexUrl = _getIndexUrl();
            
            String response = _http.get( indexUrl, "application/xml" );
            response = _securityManager.decryptWithPrivateKey( response );
                        
            Document xml = Util.getDocumentFromString( response );
            NodeList nodes = xml.getElementsByTagName( "url" );

            ArrayList<String> urls = new ArrayList<String>();

            for ( int i = 0; i < nodes.getLength(); ++i )
                urls.add( nodes.item( i ).getTextContent() );

            return urls;
        }
        catch ( Exception e )
        {
            throw new ServletException( e );
        }
    }
}
